--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_motoori_kosuzu = General:new(extension, "hy_motoori_kosuzu", "jin_k", 4, 4, General.Female)
    local collect_books = fk.CreateSkill {
        name = "collect_books",
    }
    collect_books:addEffect("viewas", {
        mute_card = false,
        card_num = 1,
        card_filter = function(self, player, to_select, selected)
            return #selected == 0 and table.contains(player:getCardIds("h"), to_select)
        end,
        interaction = function(self, player)
            local choices = { "ex_nihilo", "iron_chain", "fire_attack" }
            if player:getMark("collect_books_ex_nihilo-phase") > 0 then
                table.removeOne(choices, "ex_nihilo")
            end
            if player:getMark("collect_books_iron_chain-phase") > 0 then
                table.removeOne(choices, "iron_chain")
            end
            if player:getMark("collect_books_fire_attack-phase") > 0 then
                table.removeOne(choices, "fire_attack")
            end
            if #choices == 0 then
                return
            end
            return UI.ComboBox { choices = choices }
        end,
        prompt = function(self, player, selected_cards, selected)
            return "collect_books_prompt"
        end,
        view_as = function(self, player, cards)
            if #cards ~= 1 or not self.interaction.data then
                player:setMark("collect_books", 0)
                return
            end
            player:setMark("collect_books", cards[1])
            local card = Fk:cloneCard(self.interaction.data)
            table.insertIfNeed(card.skillNames, "collect_books")
            return card
        end,
        before_use = function(self, player, use)
            player:addToPile("collect_books_book", player:getMark("collect_books"), true, collect_books.name)
            player.room:setPlayerMark(player, "collect_books_" .. self.interaction.data .. "-phase", 1)
            player.room:setPlayerMark(player, "collect_books", 0)
        end,
        enabled_at_play = function(self, player)
            return (player:getMark("collect_books_ex_nihilo-phase") == 0 or player:getMark("collect_books_iron_chain-phase") == 0 or player:getMark("collect_books_fire_attack-phase") == 0) and
                not player:isKongcheng()
        end,
    })
    local seek_adventure = fk.CreateSkill {
        name = "seek_adventure",
        tags = {
            Skill.Limited,
        }
    }
    seek_adventure:addEffect("active", {
        min_card_num = 1,
        max_card_num = 3,
        card_filter = function(self, player, to_select, selected)
            return #selected < 3 and table.contains(player:getCardIds("h"), to_select)
        end,
        can_use = function(self, player)
            return player:usedSkillTimes(seek_adventure.name, Player.HistoryGame) == 0 and not player:isKongcheng()
        end,
        prompt = function(self, selected, selected_cards)
            return "seek_adventure_prompt"
        end,
        on_use = function(self, room, cardUseEvent)
            local count = #cardUseEvent.cards
            local player = room.current
            for _, id in ipairs(cardUseEvent.cards) do
                player:addToPile("collect_books_book", id)
            end
            if count == 3 then
                room:loseHp(player, 2, seek_adventure.name)
            end
            for i = 1, count, 1 do
                if not player.dead then
                    local _, data = player.room:askToUseActiveSkill(player, {
                        skill_name = "seek_adventure_viewas",
                        prompt = "seek_adventure_viewas_prompt",
                        cancelable = false
                    })
                    if data then
                        local card = Fk:cloneCard(data.interaction)
                        local mark = player:getMark("seek_adventure")
                        if mark == 0 then mark = {} end
                        table.insert(mark, card.trueName)
                        player.room:setPlayerMark(player, "seek_adventure", mark)
                        room:useCard {
                            from = player,
                            tos = data.targets,
                            card = card,
                        }
                    end
                end
            end
        end
    })
    local seek_adventure_viewas = fk.CreateSkill {
        name = "seek_adventure_viewas",
    }
    seek_adventure_viewas:addEffect("viewas", {
        mute = true,
        card_filter = Util.FalseFunc,
        interaction = function(self, player)
            local names = {}
            local mark = player:getTableMark("seek_adventure")
            for _, name in ipairs(Fk:getAllCardNames("t")) do
                local card = Fk:cloneCard(name)
                if not table.contains(mark, card.name) then
                    if (Fk.currentResponsePattern == nil and player:canUse(card)) or (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
                        table.insertIfNeed(names, card.name)
                    end
                end
            end
            if #names == 0 then return end
            return UI.ComboBox { choices = names }
        end,
        prompt = function(self, selected, selected_cards)
            return "seek_adventure_viewas_prompt"
        end,
        view_as = function(self, player, cards)
            if not self.interaction.data then return end
            local card = Fk:cloneCard(self.interaction.data)
            table.insertIfNeed(card.skillNames, seek_adventure.name)
            return card
        end,
    })
    local monster_attach = fk.CreateSkill {
        name = "monster_attach",
    }
    monster_attach:addEffect("viewas", {
        mute_card = false,
        card_num = 0,
        card_filter = Util.FalseFunc,
        interaction = function(self, player)
            local choices = {}
            if Self:getMark("monster_attach_duel-phase") == 0 and #player:getPile("collect_books_book") >= 1 then
                table.insert(choices, "duel")
            end
            if Self:getMark("monster_attach_fire_attack-phase") == 0 and #player:getPile("collect_books_book") >= 4 then
                table.insert(choices, "fire_attack")
            end
            if #choices == 0 then
                return
            end
            return UI.ComboBox { choices = choices }
        end,
        prompt = function(self, selected, selected_cards)
            return "monster_attach_prompt"
        end,
        view_as = function(self, player, cards)
            if not self.interaction.data then return end
            local card = Fk:cloneCard(self.interaction.data)
            table.insertIfNeed(card.skillNames, monster_attach.name)
            return card
        end,
        before_use = function(self, player, use)
            player.room:setPlayerMark(player, "monster_attach_" .. self.interaction.data .. "-phase", 1)
        end,
        enabled_at_play = function(self, player)
            local choices = {}
            if player:getMark("monster_attach_duel-phase") == 0 and #player:getPile("collect_books_book") >= 1 then
                table.insert(choices, "duel")
            end
            if player:getMark("monster_attach_fire_attack-phase") == 0 and #player:getPile("collect_books_book") >= 4 then
                table.insert(choices, "fire_attack")
            end
            return #choices > 0
        end
    })
    monster_attach:addEffect(fk.TargetSpecifying, {
        mute = true,
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(monster_attach.name) and target == player and data.card and data.firstTarget and table.contains(data.card.skillNames, "monster_attach") and
            #player:getPile("collect_books_book") >= 7
        end,
        on_cost = function(self, event, target, player, data)
            local targets = HY.AskForAddTarget(player, 1, false, false,
                "monster_attach_choose:::" .. data.card:toLogString(), monster_attach.name, data)
            if #targets > 0 then
                event:setCostData(self, targets[1].id)
                return true
            end
        end,
        on_use = function(self, event, target, player, data)
            HY.ChangeTarget(data, player.room:getPlayerById(event:getCostData(self)))
        end,
    })
    local join_youkai = fk.CreateSkill {
        name = "join_youkai",
        tags = {
            Skill.Limited
        },
    }
    join_youkai:addEffect(fk.EventPhaseStart, {
        can_trigger = function(self, event, target, player, data)
            return target == player and player:hasSkill(join_youkai.name) and player:usedSkillTimes(join_youkai.name, Player.HistoryGame) == 0 and player.phase == Player.Start and
                #player:getPile("collect_books_book") > 0
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            room:changeMaxHp(player, -1)
            if player:isWounded() then
                room:recover({
                    who = player,
                    num = 1,
                    skillName = join_youkai.name
                })
            end
            if #player.player_cards[Player.Judge] > 0 then
                room:throwCard(player.player_cards[Player.Judge], join_youkai.name, player, player)
            end
            room:handleAddLoseSkills(player,
                "-collect_books|monster_attach", nil, true,
                false)
        end,
    })
    local receive_protection = fk.CreateSkill {
        name = "receive_protection",
        tags = {
            Skill.Lord,
        },
        attached_skill_name = "receive_protection_active&",
    }
    receive_protection:addAcquireEffect(function(self, player, is_start)
        local room = player.room
        for _, p in ipairs(room:getOtherPlayers(player, false)) do
            if p.kingdom == "jin_k" then
                room:handleAddLoseSkills(p, "receive_protection_active&", nil, false, true)
            else
                room:handleAddLoseSkills(p, "-receive_protection_active&", nil, false, true)
            end
        end
    end)
    receive_protection:addEffect(fk.AfterPropertyChange, {
        can_refresh = function(self, event, target, player, data)
            return target == player
        end,
        on_refresh = function(self, event, target, player, data)
            local room = player.room
            if player.kingdom == "jin_k" and table.find(room.alive_players, function(p)
                    return p ~= player and p:hasSkill(receive_protection.name, true)
                end) then
                room:handleAddLoseSkills(player, "receive_protection_active&", nil, false, true)
            else
                room:handleAddLoseSkills(player, "-receive_protection_active&", nil, false, true)
            end
        end,
    })
    local receive_protection_active = fk.CreateSkill {
        name = "receive_protection_active&",
    }
    receive_protection_active:addEffect("active", {
        anim_type = "support",
        card_num = 1,
        card_filter = function(self, player, to_select, selected)
            return #selected == 0 and Fk:getCardById(to_select).type == Card.TypeBasic
        end,
        target_filter = Util.FalseFunc,
        can_use = function(self, player)
            if player:usedSkillTimes(receive_protection_active.name, Player.HistoryPhase) < 1 and player.kingdom == "jin_k" then
                return table.find(Fk:currentRoom().alive_players, function(p)
                    return p:hasSkill("receive_protection")
                end)
            end
            return false
        end,
        prompt = function(self, player, selected_cards, selected_targets)
            local room = Fk:currentRoom()
            local targets = table.filter(room.alive_players, function(p)
                return p:hasSkill("receive_protection")
            end)
            return "receive_protection_active_prompt::" .. targets[1].id
        end,
        on_use = function(self, room, cardUseEvent)
            local player = cardUseEvent.from
            room:notifySkillInvoked(player, "receive_protection")
            player:broadcastSkillInvoke("receive_protection")
            local targets = table.filter(room.alive_players, function(p)
                return p:hasSkill("receive_protection")
            end)
            local target
            if #targets == 1 then
                target = targets[1]
            else
                target = room:askToChoosePlayers(player, {
                    targets = targets,
                    min_num = 1,
                    max_num = 1,
                    skill_name = receive_protection_active.name,
                    cancelable = false,
                    no_indicate = true,
                })[1]
            end
            if not target then
                return false
            end
            room:doIndicate(cardUseEvent.from, { target })
            room:moveCardTo(cardUseEvent.cards, Player.Hand, target, fk.ReasonGive, receive_protection_active.name, nil, true)
        end,
    })
    local book_clear = fk.CreateSkill {
        name = "book_clear",
    }
    book_clear:addEffect(fk.Deathed, {
        global = true,
        can_refresh = function(self, event, target, player, data)
            return #player:getPile("collect_books_book") > 0 and data.who == player
        end,
        on_refresh = function(self, event, target, player, data)
            player.room:moveCardTo(player:getPile("collect_books_book"), Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile, nil, "collect_books_book")
        end
    })
    extension:loadSkillSkels { collect_books, seek_adventure, seek_adventure_viewas, join_youkai, receive_protection, receive_protection_active, monster_attach, book_clear }
    hy_motoori_kosuzu:addSkill("collect_books")
    hy_motoori_kosuzu:addSkill("seek_adventure")
    hy_motoori_kosuzu:addSkill("join_youkai")
    hy_motoori_kosuzu:addSkill("receive_protection")
    hy_motoori_kosuzu:addRelatedSkill("monster_attach")
    Fk:loadTranslationTable {
        ["hy_motoori_kosuzu"] = "本居小铃",
        ["#hy_motoori_kosuzu"] = "双面探险者",
        ["illustrator:hy_motoori_kosuzu"] = "MaNue",
        ["designer:hy_motoori_kosuzu"] = "黑曜人形",
        ["cv:hy_motoori_kosuzu"] = "",

        ["collect_books"] = "集书",
        [":collect_books"] = "出牌阶段每牌名限一次，你可以将一张手牌置于你的武将牌上，称为“书”，然后视为使用【无中生有】、【铁索连环】或【火攻】。",
        ["collect_books_prompt"] = "集书：选择要使用的牌",
        ["collect_books_book"] = "书",

        ["seek_adventure"] = "求奇",
        [":seek_adventure"] = "限定技，出牌阶段，你可以将至多三张手牌作为“书”置于武将牌上，然后视为使用等量的不同牌名的普通锦囊牌。若你以此法失去了三张手牌，你失去2点体力。",
        ["seek_adventure_prompt"] = "求奇：选择至多三张手牌并视为使用等量不同的普通锦囊牌",

        ["seek_adventure_viewas"] = "求奇",
        ["seek_adventure_viewas_prompt"] = "选择并使用一张普通锦囊牌",

        ["join_youkai"] = "入魔",
        [":join_youkai"] = "限定技，准备阶段，若你的武将牌上有“书”，你可以失去1点体力上限，回复1点体力并弃置判定区内所有牌，然后失去“集书”并获得“<a href=':monster_attach'>妖凭</a>”。",

        ["monster_attach"] = "妖凭",
        [":monster_attach"] = "出牌阶段每牌名限一次，若你的“书”的数量：<br>&nbsp;&nbsp;&nbsp;&nbsp;不小于1，你可以视为使用【决斗】；<br>&nbsp;&nbsp;&nbsp;&nbsp;不小于4，你可以视为使用【火攻】；<br>&nbsp;&nbsp;&nbsp;&nbsp;不小于7，你以此法使用牌时可以增加一个目标。",
        ["monster_attach_choose"] = "妖凭：为%arg增加一个目标",
        ["monster_attach_prompt"] = "妖凭：视为使用一张牌",

        ["receive_protection"] = "受护",
        [":receive_protection"] = "主公技，其他人势力角色出牌阶段限一次，其可以交给你一张基本牌。",

        ["receive_protection_active&"] = "受护",
        [":receive_protection_active&"] = "出牌阶段限一次，你可以交给主公一张基本牌。",
        ["receive_protection_active_prompt"] = "受护：交给%dest一张基本牌"
    }
end
